package main

import (
	"fmt"
	"os"
)

// func 函数名（参数）（返回）多返回，不支持函数重载也就是函数名不能重复
func mutilple(var1, var2 int) (sum int, minus int) { //也可以不命名int，但命名都要命名
	sum = var1 + var2
	return sum, var1 - var2
}

// 传入无限参数
func allin(args ...int) {
	for k, v := range args {
		fmt.Print(k, v)
	}
}

// 万能参数，判断类型
func allinall(args ...interface{}) {
	for _, v := range args {
		switch v.(type) {
		case int:
			fmt.Print("int")
		case string:
			fmt.Print("string")
		default:
			fmt.Print("other")
		}
	}
}

// 闭包
func closure() func(int64) int64 {
	var s int64 = 0
	return func(i int64) int64 {
		s += i
		return s
	}
}

// defer延迟
func deferAction() {
	handle, error := os.Open("hello.txt")
	error = error
	defer handle.Close() //无论错误也会关闭，先进后出
}

// 先进后出
func deferAction2(v1, v2 int) int {
	defer fmt.Print(v1)
	defer fmt.Print(v2)
	sum := v1 + v2
	fmt.Print(sum)
	return sum
}

// 函数作为函数的参数
func funAsArgs(funcNm func(int, int) (int, int), v1, v2 int) (int, int) {
	return funcNm(v1, v2)
}
func avar(v1, v2 int) (sum int, minus int) { //go 推荐命名
	sum = v1 + v2
	minus = v1 - v2
	return //可以不写默认返回相同名字的 = return sum, minus
}

type Boolen func(int) bool

// 函数作为值传递，例子判断传递是否为偶数奇数
func isEven(i int) bool {
	if i%2 == 0 {
		return true
	}
	return false
}

func isOdd(i int) bool {
	if i%2 != 0 {
		return true
	}
	return false
}

func slices(s []int, boolean Boolen) (out []int) {
	for _, v := range s {
		if boolean(v) {
			out = append(out, v)
		}
	}
	return out
}

// 特殊函数 init()和main(),默认且不能传参，显示全局变量，然后init先执行初始化，最后main
func init() {
	fmt.Print("this is init")
}

func main() {
	fmt.Print(mutilple(1, 2))
	allin(1, 2, 3, 4)
	allinall(1, "bb", 1.2)
	//匿名函数（只使用一次）而且必须被赋值给变量
	sum := func(var1, var2 int) int {
		return var1 + var2
	}(1, 2)
	fmt.Println(sum)
	func2 := closure()
	fmt.Println(func2(1))
	deferAction2(1, 2)
	sums, minus := funAsArgs(avar, 2, 1)
	fmt.Print(sums, minus)
	fmt.Println("-------------------")
	slice := []int{1, 2, 3, 4, 5, 6}
	evenout := slices(slice, isEven) //函数值传递
	oddout := slices(slice, isOdd)
	fmt.Println(evenout, oddout)
}
